package com.ybg.ebs_memory.data;

import com.ybg.ebs_memory.util.Util;

import java.util.*;

public class Data {
    private final String[][] menuNames =
            {
                    {"用户注册","用户登录"},
                    {
                        "修改密码","充值","查看用户信息",
                        "所有分类","所有商品",
                        "加入购物车","移出购物车","查看购物车",
                        "下单","支付订单","所有订单",
                        "退出系统"
                    }
            };
    private final String[] categoryNames = {"手机","电脑"};
    private final String[] customerNames = {"henry","ariel"};
    private final String[] productNames = {
            "欧普（OPPO）","华为（Huawei）","IQOO","小米","真我","魅族","联想","LG","红米（Redmi）","索尼（Sony）",
            "戴尔（Dell）","惠普（HP）","联想（Lenovo）","华为（Huawei）","浪潮（Inspur）","思科（Cisco）","甲骨文（Oracle）","富士通（Fujitsu）","超微（Supermicro）","新华三（H3C）"
    };

    private List<Menu> menus;
    private List<Category> categories;
    private List<Customer> customers;
    private List<Product> products;
    private List<Order> orders;
    private int orderId = 0;
    private Customer loginCustomer;

    public Data() {
        menus = new ArrayList<>();
        categories = new ArrayList<>();
        customers = new ArrayList<>();
        products = new ArrayList<>();
        orders = new ArrayList<>();
        initMenus();
        System.out.println("EBS - 菜单初始化完成");
        initCategories();
        System.out.println("EBS - 商品分类初始化完成");
        initCustomers();
        System.out.println("EBS - 客户初始化完成");
        initProducts();
        System.out.println("EBS - 商品初始化完成");
    }

    public boolean isLogin(){
        return Objects.nonNull(loginCustomer);
    }
    private void addMenu(int id, String name){
        menus.add(new Menu(id,name));
    }
    private void initMenus(){
        for (String[] menuArr : menuNames) {
            for (int i = 0; i < menuArr.length; i++) {
                addMenu(i+1,menuArr[i]);
            }
        }
    }
    public int showNotLoginMenus(){
        System.out.println("\n---------------- ES - 我的菜单 ----------------");
        for (int i = 0; i < 2; i++) {
            menus.get(i).showLine();
        }
        System.out.println("---------------- ES - 我的菜单 ----------------");
        return Util.choose("请选择菜单：",1,2);
    }
    public int showLoginMenus(){
        System.out.println("\n---------------- ES - "+loginCustomer.getUsername()+" - 我的菜单 ----------------");
        for (int i = 2; i < menus.size(); i++) {
            menus.get(i).showLine();
        }
        System.out.println("---------------- ES - "+loginCustomer.getUsername()+" - 我的菜单 ----------------");
        return Util.choose("请选择菜单：",1,12);
    }

    private void addCategory(int id,String name){
        categories.add(new Category(id,name));
    }
    private void initCategories(){
        for (int i = 0; i < categoryNames.length; i++) {
            addCategory(i+1,categoryNames[i]);
        }
    }
    public void showCategories(){
        System.out.println("---------------- ES - 商品分类 ----------------");
        for (Category category : categories) {
            category.showLine();
        }
    }

    public void addCustomer(String username,String password,float balance){
        customers.add(new Customer(username, password, balance));
    }
    private void initCustomers(){
        for (int i = 0; i < customerNames.length; i++) {
            addCustomer(customerNames[i],customerNames[i], 1000);
        }
    }
    public void register(){
        String username;
        do {
            username = Util.input("请输入账号：","\\w{3,10}");
            boolean exists = false;
            for (Customer customer : customers) {
                if (customer.getUsername().equals(username)) {
                    exists = true;
                    break;
                }
            }
            if(!exists){
                break;
            }
            System.out.println(username+" 已存在，需要重新输入");
        }while (true);
        String password = Util.input("请输入密码：","[a-zA-Z0-9]{6}");
        float charge = Float.parseFloat(Util.input("请输入充值金额：", "[1-9]\\d*"));
        addCustomer(username, password, charge);
        System.out.println(username+" 注册成功");
    }
    public void login(){
        String username = Util.input("请输入账号：",".*");
        String password = Util.input("请输入密码：",".*");
        for (Customer customer : customers) {
            if(customer.getUsername().equals(username) && customer.getPassword().equals(password)){
                loginCustomer = customer;
                System.out.println(username +"登录成功");
                return;
            }
        }
        System.out.println("账号和密码错误，登录失败");
    }
    public void logout(){
        if(Objects.nonNull(loginCustomer)){
            String username = loginCustomer.getUsername();
            loginCustomer = null;
            System.out.println(username+" 退出系统成功！");
        }
    }
    public void modifyPass(){
        String password = Util.input("请输入原密码：",".*");
        String newPass = Util.input("请输入新密码：","[a-zA-Z0-9]{6}");
        String repeatPass = Util.input("请确认新密码：",".*");
        if(!password.equals(loginCustomer.getPassword())){
            System.out.println("原密码有误\n");
            modifyPass();
        }else if(!newPass.equals(repeatPass)){
            System.out.println("两次密码输入不一致\n");
            modifyPass();
        }else{
            loginCustomer.setPassword(newPass);
            System.out.println("密码修改成功！\n");
        }
    }
    public void charge(){
        float charge = Float.parseFloat(Util.input("请输入充值金额：", "[1-9]\\d*"));
        loginCustomer.setBalance(charge);
        System.out.println(String.format("%s 充值 ￥%.2f 成功，当前余额 ￥%.2f。"
                ,loginCustomer.getUsername(),charge,loginCustomer.getBalance()));
    }
    public void showMe(){
        loginCustomer.showMe();
    }
    public void addToChart(){
        Product product = showProducts(1, true);
        if(Objects.nonNull(product)){
            int count = Util.choose("请输入商品数量：", 1, 10);
            loginCustomer.setCart(product,count);
            System.out.printf("商品 %s 数量 %d 加入购物车成功！\n",product.getName(),count);
        }
        String goon = Util.input("是否继续（Y/N）：", "Y|N");
        if(goon.equalsIgnoreCase("y")){
            addToChart();
        }else{
            System.out.println("本轮加入购物车结束！");
        }
    }
    public void removeFromChart(){
        if(loginCustomer.getCart().isEmpty()){
            System.out.println("购物车空空如也！");
            return;
        }
        ArrayList<Map.Entry<Product, Integer>> entries = new ArrayList<>(loginCustomer.getCart().entrySet());
        int id = 0;
        for (Map.Entry<Product, Integer> e : entries) {
            Product product = e.getKey();
            Integer count = e.getValue();
            System.out.printf("[ %d\t]\t",++id);
            product.showCartItem(count);
        }
        int rmId = Util.choose("请输入移除商品编号（输0放弃）：", 1, entries.size());
        if(rmId > 0){
            Product key = entries.get(rmId - 1).getKey();
            loginCustomer.getCart().remove(key);
            System.out.println("从购物车移除商品 "+key.getName()+" 成功！");
        }
        String goon = Util.input("是否继续（Y/N）：", "Y|N");
        if(goon.equalsIgnoreCase("y")){
            removeFromChart();
        }else{
            System.out.println("本轮移除购物车结束！");
        }
    }
    public float showCart(){
        System.out.println("---------------- ES - 购物车 ----------------");
        float total = 0;
        for (Map.Entry<Product, Integer> e : loginCustomer.getCart().entrySet()) {
            Product product = e.getKey();
            Integer count = e.getValue();
            float item = product.showCartItem(count);
            total += item;
        }
        System.out.println("---------------- ES - 购物车 ----------------");
        System.out.printf("购物车总金额：%.2f（元）\n",total);
        return total;
    }
    public void placeOrder(){
        float total = showCart();
        Map<Product,Integer> orderItems = new HashMap<>();
        orderItems.putAll(loginCustomer.getCart());
        loginCustomer.getCart().clear();
        Order order = addOrder(loginCustomer.getUsername(), orderItems);
        // 余额判定
        if(loginCustomer.getBalance()>=total){
            // 扣除余额
            loginCustomer.pay(order.getAmount());
            // 更新订单状态
            order.setStatus(1);
            System.out.println("下单并支付完成");
        }else{
            System.out.println("已下单，因余额不足未支付");
        }
        order.showDetails(loginCustomer.getUsername());
    }
    public void payOrder(){
        List<Order> orders = showMyOrders(true);
        if(orders.isEmpty()){
            System.out.println("无待支付订单！");
            return;
        }
        int choice = Util.choose("请选择商品编号（输0放弃）：", 1, orders.size());
        if(choice==0){
            System.out.println("您已放弃支付！");
            return;
        }
        Order order = orders.get(choice - 1);
        if (loginCustomer.getBalance()>=order.getAmount()) {
            loginCustomer.pay(order.getAmount());
            order.setStatus(1);
            System.out.printf("您的订单 %d 支付成功\n",order.getId());
        }else{
            System.out.println("您的余额不足，请充值！");
        }
    }

    private void addProduct(int id, String name, float price, int categoryId){
        products.add(new Product(id, name, price, categoryId));
    }
    private void initProducts(){
        int i = 0;
        for (String productName : productNames) {
            int categoryId = (i/10)+1;
            addProduct(
                    i+1,
                    productName,
                    Util.randPrice(categoryId==1 ? 3000 : 1200,categoryId==1 ? 10000 : 80000),
                    categoryId
            );
            i++;
        }
    }
    public Product showProducts(int pageNo,boolean choose){
        final int pageSize = 5;
        int pageTotal = (int)Math.ceil(products.size()/pageSize);
        int from = (pageNo-1)*pageSize, to = (pageNo*pageSize>products.size()?products.size():pageNo*pageSize);
        System.out.println(String.format("---------------- ES - 商品列表 - Page.%d Total.%d ----------------",pageNo,pageTotal));
        for (int i = from; i < to; i++) {
            Product product = products.get(i);
            product.showLine(categoryNames[product.getCategoryId()-1]);
        }
        if (choose) {
            int choice = Util.choose("请选择商品编号（输0放弃）：", from+1, to);
            if(choice==0){
                String input = Util.input("是否查看下一页（Y/N）", "Y|N");
                if(input.equalsIgnoreCase("y")){
                    if(pageNo<pageTotal){
                        return showProducts(pageNo+1,choose);
                    }else{
                        System.out.println("已是最后一页");
                    }
                }
            }else{
                return products.get(choice-1);
            }
        }else{
            String input = Util.input("是否查看下一页（Y/N）", "Y|N");
            if(input.equalsIgnoreCase("y")){
                if(pageNo<pageTotal){
                    return showProducts(pageNo+1,choose);
                }else{
                    System.out.println("已是最后一页");
                }
            }
        }
        return null;
    }

    private Order addOrder(String username,Map<Product,Integer> products){
        Order order = new Order(++orderId, username, products);
        orders.add(order);
        return order;
    }
    public List<Order> showMyOrders(boolean unpaid){
        String username = loginCustomer.getUsername();
        List<Order> rtnOrders = null;
        if(unpaid){
            rtnOrders = new ArrayList<>();
        }
        int id = 0;
        System.out.println("---------------- ES - 我的订单 ----------------");
        for (Order order : orders) {
            if(order.getUsername().equals(username)){
                if(unpaid){
                    if(order.getStatus()==0){
                        System.out.printf("[ %d\t] ",++id);
                        order.showLine(username);
                        rtnOrders.add(order);
                    }
                }else{
                    order.showLine(username);
                }
            }
        }
        System.out.println("---------------- ES - 我的订单 ----------------");
        return rtnOrders;
    }
}
